/**
 * Copyright (C), 2015-2018, XXX有限公司
 * FileName: LogAop
 * Author:   zhouheng
 * Date:     2018/6/24 11:25
 * Description: 日志增强AOP类
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.hengby.hengcrud.core.aop;

import com.hengby.hengcrud.core.common.annotation.BussinessLog;
import com.hengby.hengcrud.core.common.dictmap.base.AbtractDictMap;
import com.hengby.hengcrud.core.log.LogManager;
import com.hengby.hengcrud.core.log.LogObjectHolder;
import com.hengby.hengcrud.core.log.factory.LogTaskFactory;
import com.hengby.hengcrud.core.shiro.ShiroKit;
import com.hengby.hengcrud.core.shiro.ShiroUser;
import com.hengby.hengcrud.core.support.HttpKit;
import com.hengby.hengcrud.core.util.Contrast;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

/**
 * 〈一句话功能简述〉<br> 
 * 〈日志增强AOP类〉
 *
 * @author zhouheng
 * @create 2018/6/24
 * @since 1.0.0
 */
@Aspect
@Component
public class LogAop {

    @Pointcut(value = "@annotation(com.hengby.hengcrud.core.common.annotation.BussinessLog)")
    public void cut(){

    }

    @Around("cut()")
    public Object recordSysLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
        Object object = proceedingJoinPoint.proceed();

        handle(proceedingJoinPoint);

        return object;
    }

    private void handle(ProceedingJoinPoint proceedingJoinPoint) throws Exception {
        Signature signature = proceedingJoinPoint.getSignature();
        if (!(signature instanceof MethodSignature)){
            throw new IllegalArgumentException("该注解只能用于方法");
        }

        MethodSignature methodSignature = (MethodSignature)signature;

        Object target = proceedingJoinPoint.getTarget();

        Method method = target.getClass().getMethod(methodSignature.getName(),methodSignature.getParameterTypes());

        String methodName = method.getName();

        //如果当前用户未登录，不做日志
        ShiroUser user = ShiroKit.getUser();
        if (null == user) {
            return;
        }
        String className = proceedingJoinPoint.getTarget().getClass().getName();

        Object[] prams = method.getParameters();
        BussinessLog bussinessLog = method.getAnnotation(BussinessLog.class);
        String bussinessName =  bussinessLog.value();
        String key = bussinessLog.key();
        Class<? extends AbtractDictMap> dictClass = bussinessLog.dict();

        String msg = "";

        if (bussinessName.contains("修改") || bussinessName.contains("编辑")){
            // pojo1 pojo2
            Object obj1 = LogObjectHolder.me().get();
            Map<String,String> obj2 = new HashMap<>();
            obj2 = HttpKit.getRequestParameters();

            // 比较obj1 与 obj2 不同之处
            msg = Contrast.contrastObj(dictClass,key,obj1,obj2);

        }else {
            Map<String,String> parameters = new HashMap<>();
            parameters = HttpKit.getRequestParameters();
            AbtractDictMap dictMap = (AbtractDictMap) dictClass.newInstance();
            msg = Contrast.parseMutiKey(dictMap,key,parameters);
        }

        LogManager.me().executeLog(LogTaskFactory.bussinessLog(user.getId(),
                bussinessName, className, methodName, msg));

    }

}